package com.ruoyi.commodity.service.impl;

import com.ruoyi.commodity.mapper.PaymentMethodMapper;
import com.ruoyi.commodity.mapper.VendorMapper;
import com.ruoyi.commodity.mapper.productCatesMapper;
import com.ruoyi.commodity.service.IVendorService;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PaymentMethod;
import com.ruoyi.common.core.domain.ProductCates;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.Vendor;
import com.ruoyi.common.core.domain.depot.Monetary;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.NumberUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 供应商管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-09-18
 */
@Slf4j
@Service
public class VendorServiceImpl implements IVendorService 
{
    @Autowired
    private VendorMapper vendorMapper;
    @Autowired
    private productCatesMapper productCatesMapper;
    @Autowired
    private PaymentMethodMapper paymentMethodMapper;
    /**
     * 查询供应商管理
     * 
     * @param id 供应商管理主键
     * @return 供应商管理
     */
    @Override
    public Vendor selectVendorById(Long id)
    {
        return vendorMapper.selectVendorById(id);
    }

    /**
     * 查询供应商管理列表
     * 
     * @param vendor 供应商管理
     * @return 供应商管理
     */
    @Override
    @DataScope(VendorAlias = "v")
    public List<Vendor> selectVendorList(Vendor vendor)
    {
        return vendorMapper.selectVendorList(vendor);
    }

    /**
     * 新增供应商管理
     * 
     * @param vendor 供应商管理
     * @return 结果
     */
    @Override
    public int insertVendor(Vendor vendor)
    {
        vendor.setAddTime(DateUtils.getNowDate());
        return vendorMapper.insertVendor(vendor);
    }

    /**
     * 修改供应商管理
     * 
     * @param vendor 供应商管理
     * @return 结果
     */
    @Override
    public int updateVendor(Vendor vendor)
    {
        vendor.setUpdateTime(DateUtils.getNowDate());
        return vendorMapper.updateVendor(vendor);
    }

    /**
     * 批量删除供应商管理
     * 
     * @param ids 需要删除的供应商管理主键
     * @return 结果
     */
    @Override
    public int deleteVendorByIds(Long[] ids)
    {
        return vendorMapper.deleteVendorByIds(ids);
    }

    /**
     * 删除供应商管理信息
     * 
     * @param id 供应商管理主键
     * @return 结果
     */
    @Override
    public int deleteVendorById(Long id)
    {
        return vendorMapper.deleteVendorById(id);
    }

    /**
     * 生成供应商编号 10001递增
     * @return 结果
     */
    @Override
    public String selectNumber() {
        String vendorNumber = vendorMapper.selectNumber();
        if(StringUtils.isEmpty(vendorNumber)){
            return Constants.RANDOM_NUMBERS;
        }else{
            Long number = NumberUtils.parseNumber(vendorNumber, Long.class)+1;
            return number.toString();
        }
    }

    @Override
    public int batchUpdate(List<Vendor> vendorList) {
        return vendorMapper.batchUpdate(vendorList);
    }

    @Override
    public List<Vendor> selectVendorListById(Long[] ids) {
        return vendorMapper.selectVendorListById(ids);
    }

    @Override
    public List<TreeSelect> selectVendorTreeList(Vendor vendor) {
        List<Vendor> vendorList = SpringUtils.getAopProxy(this).selectVendorList(vendor);
        return buildVendorTreeSelect(vendorList);
    }

    @Override
    public List<Vendor> buildVendorTree(List<Vendor> vendorList) {
        List<Vendor> returnList = new ArrayList<>();
        List<Long> collect = vendorList.stream().map(Vendor::getId).collect(Collectors.toList());
        for (Vendor vendor : vendorList){
            //如果是顶节点，遍历该父节点下的所以子节的
            if(!collect.contains(vendor.getParentId())){
                recursionFn(vendorList,vendor);
                returnList.add(vendor);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = vendorList;
        }
        return returnList;
    }

    @Override
    public List<TreeSelect> buildVendorTreeSelect(List<Vendor> vendorList) {
        List<Vendor> vendorTrees = buildVendorTree(vendorList);
        return vendorTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 导入供应商模版数据
     * @param file
     * @return
     */
    @Override
    @Transactional
    public int importVendorExcel(MultipartFile file) {
        int rows = 0;
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = new XSSFWorkbook(inputStream)) {

            Sheet sheet = workbook.getSheetAt(0); // 读取第一个工作表
            int rowCount = sheet.getPhysicalNumberOfRows();
            if (rowCount <= 1) {
                throw new RuntimeException("Excel 数据为空");
            }

            for (int i = 1; i < rowCount; i++) { // 从第二行开始读取（第一行是表头）
                Row row = sheet.getRow(i);
                if (row == null) continue;

                Vendor vendor = new Vendor();
                vendor.setPaymentId(0L);
                vendor.setDeleteStatus("0");
                vendor.setVendorNumber(selectNumber());  // 供应商编号

                vendor.setName(getCellValue(row.getCell(0)));// 供应商名称
                // 1️⃣ 校验供应商名称是否已存在
                int count = vendorMapper.checkVendorNameExists(vendor.getName());
                if (count > 0) {
                    throw new RuntimeException("第"+ (i + 1) +"行，供应商名称已存在：" + vendor.getName());
                }

                String productCatesName = getCellValue(row.getCell(1));// 供应商类别
                //查询是否存在对应的供应商类别
                ProductCates productCates = productCatesMapper.checkProductCatesNameExists(productCatesName);
                if(productCates == null){
                    throw new RuntimeException("第"+ (i + 1) +"行，供应商类别有误，请核对。");
                }
                vendor.setCatesId(productCates.getId()); // 供应商类别

                String monetaryName = getCellValue(row.getCell(2));
                Monetary monetary = new Monetary();
                monetary.setMonetaryName(monetaryName);
                monetary =  vendorMapper.selectMonetaryByName(monetary);
                if(monetary == null){
                    throw new RuntimeException("第"+ (i + 1) +"行，货币单位有误，请核对。");
                }
                vendor.setMonetaryId(monetary.getMonetaryId()); //货币单位

                vendor.setAccountBank(getCellValue(row.getCell(3)));   // 开户行
                vendor.setAccountHolder(getCellValue(row.getCell(4))); // 开户人
                vendor.setOfficeAddress(getCellValue(row.getCell(5))); // 办公地址

                String bankCards = getCellValue(row.getCell(6));
                String formattedBankCards = bankCards.replaceAll("(.{4})", "$1 ").trim();
                vendor.setBankCards(formattedBankCards);// 银行卡号

                vendor.setAccountLimit(parseBigDecimal(getCellValue(row.getCell(7)))); // 账款额度

                String paymentName = getCellValue(row.getCell(8));// 付款方式
                PaymentMethod paymentMethod = new PaymentMethod();
                paymentMethod.setPaymentName(paymentName);
                List<PaymentMethod> paymentMethods = paymentMethodMapper.selectPaymentList(paymentMethod);
                if (paymentMethods != null && !paymentMethods.isEmpty()) {
                    PaymentMethod firstPaymentMethod = paymentMethods.get(0);
                    vendor.setPaymentId(firstPaymentMethod.getId()); // 设置付款方式ID
                } else {
                    throw new RuntimeException("第"+ (i + 1) +"行，未找到匹配的付款方式: " + paymentName);
                }

                vendor.setPaymentDate(getCellValue(row.getCell(9)));        //结款天数
                vendor.setSupplierWebsite(getCellValue(row.getCell(10)));   // 供应商网站
                vendor.setPrimaryContact(getCellValue(row.getCell(11)));    // 主联系人
                vendor.setOffice(getCellValue(row.getCell(12)));            // 职务

                String phone = getCellValue(row.getCell(13));           // 电话
                if (!phone.matches("^1[3-9]\\d{9}$")) {
                    throw new RuntimeException("第"+ (i + 1) +"行，手机号格式错误：" + phone);
                }
                vendor.setPhone(phone);

                vendor.setWx(getCellValue(row.getCell(14)));                //微信
                vendor.setQq(getCellValue(row.getCell(15)));                // QQ
                vendor.setEmail(getCellValue(row.getCell(16)));             //Email
                vendor.setRatio(getCellValue(row.getCell(17)));             // 付款比例
                vendor.setVendorRemark(getCellValue(row.getCell(18)));      // 备注

                // ✅ 校验必填字段
                if (vendor.getName() == null || vendor.getName().trim().isEmpty()) {
                    throw new RuntimeException("第"+ (i + 1) +"行，供应商名称不能为空！");
                }
                if (vendor.getOfficeAddress() == null || vendor.getOfficeAddress().trim().isEmpty()) {
                    throw new RuntimeException("第"+ (i + 1) +"行，办公地址不能为空！");
                }
                if (vendor.getPrimaryContact() == null || vendor.getPrimaryContact().trim().isEmpty() ) {
                    throw new RuntimeException("第"+ (i + 1) +"行，主联系人不能为空！");
                }
                if (vendor.getPhone() == null || vendor.getPhone().trim().isEmpty()) {
                    throw new RuntimeException("第"+ (i + 1) +"行，电话不能为空！");
                }
                vendor.setAddTime(DateUtils.getNowDate());
                vendorMapper.insertVendor(vendor);
            }
            rows = rowCount - 1;
        } catch (Exception e) {
            log.error("导入 Excel 失败", e);
            throw new RuntimeException("导入 Excel 失败：" + e.getMessage());
        }

        return rows;
    }
    // 处理空字符串转换为 Long
    private Long parseLong(String value) {
        try {
            return value == null || value.isEmpty() ? null : Long.parseLong(value);
        } catch (NumberFormatException e) {
            return null;
        }
    }

    // 处理空字符串转换为 BigDecimal
    private BigDecimal parseBigDecimal(String value) {
        try {
            return value == null || value.isEmpty() ? null : new BigDecimal(value);
        } catch (NumberFormatException e) {
            return null;
        }
    }

    // 获取单元格数据
    private String getCellValue(Cell cell) {
        if (cell == null) return "";
        if (cell.getCellType() == CellType.NUMERIC) {
            return String.valueOf((long) cell.getNumericCellValue()); // 处理数字单元格
        }
        return cell.getStringCellValue().trim();
    }
    /**
     * 递归列表
     * @param vendorList 子级
     * @param vendor 父级
     */
    private void recursionFn(List<Vendor> vendorList , Vendor vendor){
        // 得到子节点列表
        List<Vendor> childList = getChildList(vendorList, vendor);
        vendor.setChildrenVendor(childList);
        for (Vendor newVendor : childList)
        {
            if (hasChild(vendorList, newVendor))
            {
                recursionFn(vendorList, newVendor);
            }
        }
    }

    /**
     * 获得子节点
     * @param vendorList
     * @param vendor
     * @return
     */
    private List<Vendor> getChildList(List<Vendor> vendorList, Vendor vendor){
        List<Vendor> returnList = new ArrayList<>();
        Iterator<Vendor> iterator = vendorList.iterator();
        while (iterator.hasNext()){
            Vendor n = (Vendor) iterator.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == vendor.getId().longValue())
            {
                returnList.add(n);
            }
        }
        return returnList;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<Vendor> vendorList, Vendor vendor)
    {
        return getChildList(vendorList, vendor).size() > 0;
    }
}
